package engine.classes.display
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;

	public class BitmapCreator
	{
		private var _display:DisplayObject;
		private var _bounds:Rectangle;
		private var _quality:Number;
		private var _matrix:Matrix = new Matrix();
		
		public function BitmapCreator(display:DisplayObject = null, quality:Number = 1)
		{
			this.setTo(display, quality);
		}
		
		public function setTo(display:DisplayObject, quality:Number = 1):void
		{
			if(this._display == display && this._quality == quality) return;
			
			this._display = display;
			this._quality = quality;
			
			this.refreshBounds();
		}
		
		public function get display():DisplayObject { return this._display; }
		public function set display(display:DisplayObject):void
		{
			if(this._display == display) return;
			this._display = display;
			
			this.refreshBounds();
		}
		
		public function get bounds():Rectangle { return this._bounds.clone(); }
		public function refreshBounds():void
		{
			if(!this._display) return;
			
			this._bounds = this._display.getBounds(this._display);
			
			this.refreshMatrix();
		}
		
		public function get quality():Number { return this._quality; }
		public function set quality(quality:Number):void
		{
			if(this._quality == quality) return;
			this._quality = quality;
			
			this.refreshMatrix();
		}
		
		public function get matrix():Matrix { return this._matrix.clone(); }
		private function refreshMatrix():void
		{
			if(!this._bounds || isNaN(this._quality)) return;
			
			this._matrix.a 		= this._quality;
			this._matrix.d 		= this._quality;
			this._matrix.tx 	= -this._bounds.left * this._quality;
			this._matrix.ty 	= -this._bounds.top * this._quality;
		}
		
		public function createBitmapData(transparent:Boolean = true):BitmapData
		{
			var width:int 	= this._bounds.width * this._quality;
			var height:int 	= this._bounds.height * this._quality;
			
			var data:BitmapData = new BitmapData(width, height, transparent, 0);
			data.draw(this._display, this._matrix);
			
			return data;
		}
		
		public function createBitmap(data:BitmapData = null, transparent:Boolean = true, smoothing:Boolean = true, position:Boolean = true):Bitmap
		{
			if(!data) data = this.createBitmapData(transparent);
			
			var bitmap:Bitmap 	= new Bitmap(data, PixelSnapping.ALWAYS, smoothing);
			bitmap.x 			= -this._matrix.tx / this._quality;
			bitmap.y 			= -this._matrix.ty / this._quality;
			bitmap.scaleX 		= 1 / this._quality;
			bitmap.scaleY 		= 1 / this._quality;
			
			if(position)
			{
				bitmap.x += this._display.x;
				bitmap.y += this._display.y;
			}
			
			return bitmap;
		}
		
		public function createBitmapSprite(data:BitmapData = null, transparent:Boolean = true, smoothing:Boolean = true):Sprite
		{
			var bitmap:Bitmap = this.createBitmap(data, transparent, smoothing, false);
			
			var sprite:Sprite 	= new Sprite();
			sprite.transform 	= this._display.transform;
			sprite.mouseEnabled = false;
			sprite.addChild(bitmap);
			
			return sprite;
		}
	}
}